package org.vt.ece3574.pictoslider.menus;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.vt.ece3574.pictoslider.GameScreen;
import org.vt.ece3574.pictoslider.PictureFileManager;
import org.vt.ece3574.pictoslider.R;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

/**
 * This class represents the Game Modes Menu activity, which allows the user to
 * select from several game options before hitting the Play Game button to start
 * the game.
 * 
 * @author Justin Scarborough
 * @author Michael Drescher
 * @author Daniel Sebacher
 */
public class GameMenu extends Activity {

	/**
	 * This string is the key for an extra on the Intent for this activity.
	 */
	private static final String IMAGE_URI = "ImageUri";

	// These integers represent the position of each item in the picture source
	// spinner
	private final static int SELECT_IMAGE = 1;
	private final static int US_PRESIDENTS = 2;
	private final static int TAKE_PICTURE = 3;

	private boolean useCamera = false;

	/**
	 * This string is a special string used by the PictureFileManager to
	 * determine whether it should read the picture from a file, or get it from
	 * the Internet.
	 */
	public final static String PRESIDENTS = "Presidents";
	/**
	 * This string provides the file name to get the shared preferences file
	 */
	public final static String GAME_PREFS = "gamePrefsFile";
	/**
	 * This string is the key for an integer representing the item last selected
	 * in the spinner. It is stored as a Shared Preference.
	 */
	private final static String LAST_SELECTED = "lastSelected";
	/**
	 * This string is the key for an integer representing difficulty. 3 for
	 * easy, 4 for medium, 5 for hard, 6 for crazy.
	 */
	public final static String DIFFICULTY = "Difficulty";

	/**
	 * This Uri represents an image file stored on the phone.
	 */
	private static Uri imageUri;

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Themes.onActivityCreateSetTheme(this);
		Themes.onActivityCreateSetContentView(this, R.layout.gamemenu);

		// Determine whether we can use the camera or not.
		useCamera = (Build.VERSION.SDK_INT > 11)
				&& (getPackageManager()
						.hasSystemFeature(PackageManager.FEATURE_CAMERA));

		// Set the text color for the TextViews on this Activity
		((TextView) findViewById(R.id.difficultyText)).setTextColor(Themes
				.textColor(this));
		((TextView) findViewById(R.id.pictureSourceText)).setTextColor(Themes
				.textColor(this));

		// Get the imageUri if it exists
		Bundle b = getIntent().getExtras();
		if (b != null) {
			imageUri = (Uri) b.get(IMAGE_URI);
		}

		// Set Spinner Listeners and Selections
		Spinner pSourceSpinner = (Spinner) findViewById(R.id.pictureSourceSpinner);
		Spinner difficultySpinner = (Spinner) findViewById(R.id.difficultySpinner);

		// Remove the camera option if necessary
		if (!useCamera) {
			String temp[] = getResources().getStringArray(
					R.array.pictureSourceArray);
			String newArray[] = new String[TAKE_PICTURE];
			for (int i = 0; i < TAKE_PICTURE; i++) {
				newArray[i] = temp[i];
			}
			ArrayAdapter<String> a = new ArrayAdapter<String>(this,
					android.R.layout.simple_spinner_item, newArray);
			a.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
			pSourceSpinner.setAdapter(a);
		}

		pSourceSpinner
				.setOnItemSelectedListener(new OnPictureItemSelectedListener());
		difficultySpinner
				.setOnItemSelectedListener(new OnDifficultySelectedListener());
		difficultySpinner.setSelection(getSharedPreferences(GAME_PREFS, 0)
				.getInt(DIFFICULTY, 3) - 3);
	}

	/** Called when the play button is pressed. */
	public void goToGameScreen(View v) {
		Intent intent = new Intent(this, GameScreen.class);
		this.finish();
		startActivity(intent);
	}

	/**
	 * Listener for the Difficulty Spinner
	 * 
	 * @author Michael
	 * 
	 */
	private class OnDifficultySelectedListener implements
			OnItemSelectedListener {

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * android.widget.AdapterView.OnItemSelectedListener#onItemSelected(
		 * android.widget.AdapterView, android.view.View, int, long)
		 */
		public void onItemSelected(AdapterView<?> parent, View view, int pos,
				long id) {
			// Update the difficulty preference
			SharedPreferences.Editor editor = getSharedPreferences(GAME_PREFS,
					0).edit();
			editor.putInt(DIFFICULTY, pos + 3);
			editor.commit();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * android.widget.AdapterView.OnItemSelectedListener#onNothingSelected
		 * (android.widget.AdapterView)
		 */
		public void onNothingSelected(AdapterView<?> arg0) {
		}

	}

	/**
	 * Listener for the Picture Source Spinner.
	 * 
	 * @author Michael Drescher
	 */
	private class OnPictureItemSelectedListener implements
			OnItemSelectedListener {

		// Ensures we only get URI's which correspond to images
		private static final String PHOTO_PICKER_RETURN_TYPE = "image/*";

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * android.widget.AdapterView.OnItemSelectedListener#onItemSelected(
		 * android.widget.AdapterView, android.view.View, int, long)
		 */
		public void onItemSelected(AdapterView<?> parent, View view, int pos,
				long id) {

			SharedPreferences settings = getSharedPreferences(GAME_PREFS, 0);
			int lastSelected = settings.getInt(LAST_SELECTED, 0);

			// If this event involves a change in item selected
			if (pos != lastSelected) {

				switch (pos) // The selected item is determined by
								// pictureSourceArray[pos]
				{
				case SELECT_IMAGE: // My Pictures
					// Open the gallery to obtain a result. When a result is
					// obtained, onActivityResult is called
					Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
					photoPickerIntent.setType(PHOTO_PICKER_RETURN_TYPE);
					startActivityForResult(photoPickerIntent, SELECT_IMAGE);
					break;

				case TAKE_PICTURE: // Camera
					// Use the camera to get a picture
					Intent takePictureIntent = new Intent(
							MediaStore.ACTION_IMAGE_CAPTURE);

					// Create a file to save the image
					imageUri = getOutputMediaFileUri(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE);

					// Set the image file name
					takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
							imageUri);

					startActivityForResult(takePictureIntent, TAKE_PICTURE);
					break;

				case US_PRESIDENTS: // US Presidents
					if (isOnline()) {
						PictureFileManager pfm = new PictureFileManager(
								getApplicationContext());
						pfm.write(Uri.parse(PRESIDENTS));
					} else {
						Toast.makeText(
								getApplicationContext(),
								"Unable to reach image server. Please check your internet connection.",
								Toast.LENGTH_LONG).show();
					}
					break;

				default: // Everything else
					PictureFileManager pfm = new PictureFileManager(
							getApplicationContext());
					pfm.write(null);
					break;
				}
			}
			// Update the last spinner-item selected
			SharedPreferences.Editor editor = settings.edit();
			editor.putInt(LAST_SELECTED, pos);
			editor.commit();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * android.widget.AdapterView.OnItemSelectedListener#onNothingSelected
		 * (android.widget.AdapterView)
		 */
		public void onNothingSelected(AdapterView<?> arg0) {
			// Do nothing
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onActivityResult(int, int,
	 * android.content.Intent)
	 */
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent i) {
		super.onActivityResult(requestCode, resultCode, i);

		// Determine where the selected image came from, and
		// save the image to internal storage.
		if (resultCode == Activity.RESULT_OK) {
			// i is null if the camera just took the picture, but we have the
			// image Uri from earlier.
			if (i != null) {
				imageUri = i.getData();
			}
			PictureFileManager pfm = new PictureFileManager(
					getApplicationContext());
			try {
				pfm.write(imageUri);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/** Create a File for saving an image or video */
	private Uri getOutputMediaFileUri(int type) {
		// To be safe, you should check that the SDCard is mounted
		// using Environment.getExternalStorageState() before doing this.

		File mediaStorageDir = new File(
				Environment
						.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
				"PictoSlider");
		// This location works best if you want the created images to be shared
		// between applications and persist after your app has been uninstalled.

		// Create the storage directory if it does not exist
		if (!mediaStorageDir.exists()) {
			if (!mediaStorageDir.mkdirs()) {
				Log.v("Camera file", "Null");
				return null;
			}
		}

		// Create a media file name
		String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
				.format(new Date());
		File mediaFile;
		mediaFile = new File(mediaStorageDir.getPath() + File.separator
				+ "IMG_" + timeStamp + ".jpg");

		return Uri.fromFile(mediaFile);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onDestroy()
	 */
	@Override
	public void onDestroy() {
		super.onDestroy();
		getIntent().putExtra(IMAGE_URI, imageUri);
	}

	/**
	 * @return True if connected to the internet, false otherwise.
	 */
	private boolean isOnline() {
		ConnectivityManager con = (ConnectivityManager) getSystemService(Activity.CONNECTIVITY_SERVICE);
		NetworkInfo n = con.getActiveNetworkInfo();
		if (n != null)
			return n.isConnectedOrConnecting();
		else
			return false;
	}
}
